package top.likeqc.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import top.likeqc.common.lang.Const;
import top.likeqc.common.lang.Result;
import top.likeqc.entity.SysRole;
import top.likeqc.entity.SysRoleMenu;
import top.likeqc.entity.SysUserRole;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 前端控制器
 *
 * @author likeqc
 * @since 2022-03-14
 */
@RestController
@RequestMapping("/sys/role")
public class SysRoleController extends BaseController {

    @GetMapping("/info/{id}")
    @PreAuthorize("hasAuthority('sys:role:list')")
    public Result info(@PathVariable("id") Long id) {
        // 获取角色
        SysRole sysRole = sysRoleService.getById(id);
        
        // 获取角色相关联的菜单 id
        List<SysRoleMenu> roleMenus = sysRoleMenuService.list(new QueryWrapper<SysRoleMenu>().eq("role_id", id));
        List<Long> menuIds = roleMenus.stream().map(p -> p.getMenuId()).collect(Collectors.toList());
        
        sysRole.setMenuIds(menuIds);
        return Result.success(sysRole);
    }
    
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('sys:role:list')")
    public Result list(String name) {
    
        Page<SysRole> pageData = sysRoleService.page(
                getPage(),
                new QueryWrapper<SysRole>().like(StringUtils.isNotBlank(name), "name", name));
    
        return Result.success(pageData);
    }
    
    @PostMapping("/save")
    @PreAuthorize("hasAuthority('sys:role:save')")
    public Result save(@Validated @RequestBody SysRole sysRole) {
        sysRole.setCreated(LocalDateTime.now());
        // sysRole.setStatu(Const.STATUS_ON);
        
        sysRoleService.save(sysRole);
        return Result.success(sysRole);
    }
    
    @PostMapping("/update")
    @PreAuthorize("hasAuthority('sys:role:update')")
    public Result update(@Validated @RequestBody SysRole sysRole) {
        sysRole.setUpdated(LocalDateTime.now());
        sysRoleService.updateById(sysRole);
        
        // 更新缓存
        sysUserService.clearUserAuthorityInfoByRoleId(sysRole.getId());
        
        return Result.success(sysRole);
    }
    
    @PostMapping("/delete")
    @PreAuthorize("hasAuthority('sys:role:delete')")
    public Result delete(@RequestBody Long[] roleIds) {
        
        sysRoleService.removeByIds(Arrays.asList(roleIds));
        
        // 同步删除缓存
        /*for (Long roleId : roleIds) {
            sysUserService.clearUserAuthorityInfoByRoleId(roleId);
        }*/
        Arrays.asList(roleIds).forEach(id -> sysUserService.clearUserAuthorityInfoByRoleId(id));
        
        // 删除相关的中间表
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("role_id", roleIds));
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().in("role_id", roleIds));
        
        return Result.success("");
    }
    
    @Transactional
    @PostMapping("/perm/{roleId}")
    @PreAuthorize("hasAuthority('sys:role:perm')")
    public Result perm(@PathVariable("roleId") Long roleId, @RequestBody Long[] menuIds) {
        
        List<SysRoleMenu> sysRoleMenus = new ArrayList<>();

        Arrays.stream(menuIds)
                .forEach(
                        menuId -> {
                            SysRoleMenu sysRoleMenu = new SysRoleMenu();
                            sysRoleMenu.setMenuId(menuId);
                            sysRoleMenu.setRoleId(roleId);

                            sysRoleMenus.add(sysRoleMenu);
                        });
        
        // 先删除原来的权限，再添加
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().eq("role_id", roleId));
        sysRoleMenuService.saveBatch(sysRoleMenus);
        // 删除缓存
        sysUserService.clearUserAuthorityInfoByRoleId(roleId);
        
        return Result.success(menuIds);
    }
}
